﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX.DirectInput;
//using System.Windows.Forms;

namespace MercuryFE
{
    public class Inputs
    {

        List<InputDevice> _inputDevices = null;

        //Control _formControl = null;
        IntPtr _handle = IntPtr.Zero;

        private Dictionary<string, InputDeviceTypeAction> _keyboardMappings = null, _mouseMappings = null, _joystickMappings = null;


        public Inputs(IntPtr winHandle, bool keyboard, bool mouse, bool joystick
            , Dictionary<string, InputDeviceTypeAction> keyboardMappings, Dictionary<string, InputDeviceTypeAction> mouseMappings
            , Dictionary<string, InputDeviceTypeAction> joystickMappings) 
        {
            _keyboardMappings = keyboardMappings;
            _mouseMappings = mouseMappings;
            _joystickMappings = joystickMappings;

            InitialiseInputs(winHandle, keyboard, mouse, joystick);
        }

        public Inputs(IntPtr winHandle, bool keyboard, bool mouse, bool joystick)
        {
            InitialiseInputs(winHandle, keyboard, mouse, joystick);
        }


        private void InitialiseInputs(IntPtr winHandle, bool keyboard, bool mouse, bool joystick)
        {
            _inputDevices = new List<InputDevice>();
            _handle = winHandle;

            DirectInput di = new DirectInput();

            // keyboards
            if (keyboard)
            {




                foreach (DeviceInstance dev in di.GetDevices(DeviceClass.Keyboard, DeviceEnumerationFlags.AttachedOnly))
                {
                    InputDeviceType idt = InputDeviceType.keyboard;

                    InputDevice inputDevice = new InputDevice(winHandle, idt, dev.InstanceGuid, dev.ProductName);
                    inputDevice.Mappings = _keyboardMappings;
                    _inputDevices.Add(inputDevice);
                }
            }

            // mice
            if (mouse)
            {


                foreach (DeviceInstance dev in di.GetDevices(DeviceClass.Pointer, DeviceEnumerationFlags.AttachedOnly))
                {
                    InputDeviceType idt = InputDeviceType.mouse;
                    InputDevice inputDevice = new InputDevice(winHandle, idt, dev.InstanceGuid, dev.ProductName);
                    inputDevice.Mappings = _mouseMappings;

                    _inputDevices.Add(inputDevice);
                }
            }

            // joysticks
            if (joystick)
            {
                foreach (DeviceInstance dev in di.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
                {
                    InputDeviceType idt = InputDeviceType.joystick;
                    InputDevice inputDevice = new InputDevice(winHandle, idt, dev.InstanceGuid, dev.ProductName);
                    inputDevice.Mappings = _joystickMappings;

                    _inputDevices.Add(inputDevice);
                }
            }


            // now initialise them all.
            foreach (InputDevice inputDevice in _inputDevices)
            {
                inputDevice.CreateDevice(di);
            }
        
        }

        public List<InputDeviceState> pollDevices(bool UseRaw)
        {
            List<InputDeviceState> states = new List<InputDeviceState>();

            foreach (InputDevice inputDevice in _inputDevices)
            {
                InputDeviceState ids = inputDevice.ReadData(UseRaw);

                if (ids != null)
                {

                    states.Add(ids);
                }

            }

            return states;


        }


        public List<InputDeviceState> pollDevices() {
            List<InputDeviceState> states = new List<InputDeviceState>();
            bool useRaw = false;

            foreach (InputDevice inputDevice in _inputDevices)
            {
                InputDeviceState ids = inputDevice.ReadData(useRaw);

                if(ids != null) {
                    switch (inputDevice.DeviceType)
                    {
                        case InputDeviceType.joystick: ids.InterfaceType = "JS";
                            break;
                        case InputDeviceType.keyboard: ids.InterfaceType = "KB";
                            break;
                        case InputDeviceType.mouse: ids.InterfaceType = "MS";
                            break;
                    }

                    states.Add(ids);
                }

            }

            return states;


        }

        public void releaseDevices()
        {
            foreach (InputDevice inputDevice in _inputDevices)
            {
                inputDevice.UnacquireDevice();
            }

        }

    }
}
